@ Title: NUMEROS PRIMOS     	                       Filename: Numprimo.s
@ Author: Evelin Verdi Vega                          Date: 13 de mayo del 2017
@ Description: BUSCA E IMPRIME LOS PRIMEROS 500 NUMEROS PRIMOS
@ Input: --
@ Output: 500 NUMEROS PRIMOS

@ :(
#
######## COde Segment  ##################################################

@ Basado en Knuth TAOCP vol. 1 147ff
@ He utilizado las etiquetas y os usos de las variables de Knuth, hasta cierto punto.

@@@@@@@@@@@@@
@ registros @
@@@@@@@@@@@@@

@ r1 apuntar a direcciones de "primos"
@ r3 numero que estamos revisando     ( N e Knuth)
@ r4 recuento de primos               ( J en Knuth)
@ r5 divisores que estamos revisando
@ r6 indice para los divisores principales
@ r7 contendra recordatorio           ( R en Knuth)
@ r8 mantendra el cociente            ( Q en Knuth)
@ r9 numeros de primos buscados.

.section     .bss
.comm prime, 2000           @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS

.section     .data
spc:                        @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS CON 3 ESPACIOS
.ascii " "
len = . - spc
nl:                         @ LINEA NUEVA
      .ascii " "
      
limit:                      @ INDICADOR DEL ULTIMO NUMERO PRIMO QUE NECESITAREMOS

      .long 500
      
.section .text
.global _start
_start:

P1:                         @ CONFIGURAION
ldr r1, =prime              @ EL PUNTO R1 ES "PRIME"
mov r0, $2                  @ EL PRIMER PRIMO ES 2
str r0, [r1]                @ ALMACENAMOS ESTE NUMERO EN "PRIME"
ldr r0, =limit
ldr r9, [r0]                @ R2 MANTIENE EL NUMERO DE PRIMOS QUE BUSCAREMOS
mov r3, $3                  @ INICIALIZA N EN 3
mov r4, $1                  @ INICIALIZA J EN 1

P2:                         @ AQUI LLEGAMOS CUANDO ENCONTRAMOS UN NUMERO PRIMO
add r4, r4, $1              @ SE INCREMENTA J
str r3,  [r1, #4]!          @ ALMACENA N EN "PRIME" (CON WRITEBACK)

P3:   
cmp r4, r9                  @ REVISA SI ESTA HECHO
bge P9                      @ SI ES ASI A P9

P4:
add r3, r3, $2              @ AÑADE 2 A N

P5:                         @ EMPIEZA A VERIFICAR LOS DIVISORES
ldr r6, =prime              @ COPIA EL PUNTERO A START DE "PRIME"
ldr r5, [r6]                @ CARGA EL PRIMER DIVISOR 
mov r7, r3                  @ COPIA N EN R
mov r8, $0                  @ INICIALIZA Q

P6:
cmp r7, r5                  @ IF R>= DIVISOR
subge r7, r7, r5            @ SUSTRAE DIVISOR DESDE R
addge r8, r8, $1            @ INCREMENTA Q
bge P6                      @ REPITE
cmp r7, $0                  @ IF R ==0 ...
beq P4                      @ N NO ES PRIMO, ASI QUE PRUEBA EL SIGUIENTE N

P7:
cmp r8, r5                  @ COMPARE Q CON EL DIVISOR
ble P2                      @ IF Q <= DIVISOR, N ES PRIMO

P8:
mov r7, r3                  @ REINICIA R7 A N
mov r8, $0                  @ REINICIA Q
ldr r5,  [r6, #4]           @ OBTIENE EL SIGUIENTE DIVISOR
bol P6                      @ DIVIDE OTRA VEZ

P9:
mov r0, $1                  @ ELIGE STDOUT
mov r4, $0                  @ USA R4 COMO UN CONTADOR TEMPORAL 
mov r5, $0                  @ R5 CUENTA EL TOTAL DE NUMEROS PRIMOS IMPRESOS
ldr r6, =prime              @ PUNTERO A "PRIME"
ldr r3, [r6]                @ CARGA EL PRIMER NUMERO PRIMO

printloop:
bl print_num                @ LLAMADA DE FUNCION
add r4, $1                  @ AÑADE UNO AL CONTADOR TEMPORAL
add r5, $1       @ Title: NUMEROS PRIMOS     	                   Filename: PrimeNumbers.s
@ Author: ALEJANDRO HINOJOSA COVARRUBIAS           Date: 13-Marzo-17
@ Description: BUSCA E IMPRIME LOS PRIMEROS 500 NUMEROS PRIMOS
@ Input: --
@ Output: 500 NUMEROS PRIMOS

@ :(
######## COde Segment  ##################################################

@ Basado en Knuth TAOCP vol. 1 147ff
@ He utilizado las etiquetas y os usos de las variables de Knuth, hasta cierto punto.

@@@@@@@@@@@@@
@ registros @
@@@@@@@@@@@@@

@ r1 apuntar a direcciones de "primos"
@ r3 numero que estamos revisando     ( N e Knuth)
@ r4 recuento de primos               ( J en Knuth)
@ r5 divisores que estamos revisando
@ r6 indice para los divisores principales
@ r7 contendra recordatorio           ( R en Knuth)
@ r8 mantendra el cociente            ( Q en Knuth)
@ r9 numeros de primos buscados.

.section     .bss
.comm prime, 2000           @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS

.section     .data
spc:                        @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS CON 3 ESPACIOS
.ascii " "
len = . - spc
nl:                         @ LINEA NUEVA
      .ascii " "
      
limit:                      @ INDICADOR DEL ULTIMO NUMERO PRIMO QUE NECESITAREMOS

      .long 500
      
.section .text
.global _start
_start:

P1:                         @ CONFIGURAION
ldr r1, =prime              @ EL PUNTO R1 ES "PRIME"
mov r0, $2                  @ EL PRIMER PRIMO ES 2
str r0, [r1]                @ ALMACENAMOS ESTE NUMERO EN "PRIME"
ldr r0, =limit
ldr r9, [r0]                @ R2 MANTIENE EL NUMERO DE PRIMOS QUE BUSCAREMOS
mov r3, $3                  @ INICIALIZA N EN 3
mov r4, $1                  @ INICIALIZA J EN 1

P2:                         @ AQUI LLEGAMOS CUANDO ENCONTRAMOS UN NUMERO PRIMO
add r4, r4, $1              @ SE INCREMENTA J
str r3,  [r1, #4]!          @ ALMACENA N EN "PRIME" (CON WRITEBACK)

P3:   
cmp r4, r9                  @ REVISA SI ESTA HECHO
bge P9                      @ SI ES ASI A P9

P4:
add r3, r3, $2              @ AÑADE 2 A N

P5:                         @ EMPIEZA A VERIFICAR LOS DIVISORES
ldr r6, =prime              @ COPIA EL PUNTERO A START DE "PRIME"
ldr r5, [r6]                @ CARGA EL PRIMER DIVISOR 
mov r7, r3                  @ COPIA N EN R
mov r8, $0                  @ INICIALIZA Q

P6:
cmp r7, r5                  @ IF R>= DIVISOR
subge r7, r7, r5            @ SUSTRAE DIVISOR DESDE R
addge r8, r8, $1            @ INCREMENTA Q
bge P6                      @ REPITE
cmp r7, $0                  @ IF R ==0 ...
beq P4                      @ N NO ES PRIMO, ASI QUE PRUEBA EL SIGUIENTE N

P7:
cmp r8, r5                  @ COMPARE Q CON EL DIVISOR
ble P2                      @ IF Q <= DIVISOR, N ES PRIMO

P8:
mov r7, r3                  @ REINICIA R7 A N
mov r8, $0                  @ REINICIA Q
ldr r5,  [r6, #4]           @ OBTIENE EL SIGUIENTE DIVISOR
bol P6                      @ DIVIDE OTRA VEZ

P9:
mov r0, $1                  @ ELIGE STDOUT
mov r4, $0                  @ USA R4 COMO UN CONTADOR TEMPORAL 
mov r5, $0                  @ R5 CUENTA EL TOTAL DE NUMEROS PRIMOS IMPRESOS
ldr r6, =prime              @ PUNTERO A "PRIME"
ldr r3, [r6]                @ CARGA EL PRIMER NUMERO PRIMO

printloop:
bl print_num                @ LLAMADA DE FUNCION
add r4, $1                  @ AÑADE UNO AL CONTADOR TEMPORAL
add r5, $1                  @ AÑADE UNO AL CONTADOR
cmp r5, r9                  @ AQUI ES DONDE TERMINAMOS?
bge exit                    @ SI ES ASI, SALIDA
cmp r4, $9                  @ AFTER 10 NUMEROS PRIMOS ...
bgt newline                 @ IMPRIME UNA NUEVA LINEA
ble space                   @ AÑADE ESPACIO



space:                      @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =spc                @ IMPRIMIR ESPACIOS
ldr r2, =len
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
bal printLoop               @ CUNTINUA IMPRIMIENDO

newline:                    @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =nl                 @ IMPRIMIR UNA NUEVA LINEA
mov r2, $1
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
mov r4, $0                  @ REINICIA EL CONTADOR TEMPORAL
bal printLoop               @ CONTINUA IMPRIMIENDO


@@@@@@@@@@@@@@@@@@@@@@
@ print_num function @
@@@@@@@@@@@@@@@@@@@@@@

  ####### Data Segment ####################################################
  
print_num:
  stmfd sp!, {r0-r9, lr}    @ PUSH REGS A LA PILA
  mov r4, $0                @ PROPONE CONTADOR DE DIVISION A ZERO
  mov r5, $1                @ PROPONE CONTADOR CHAR A 1
  
loop:                       @ DIVISION DE RUTINA
cmp r3, $9
ble stackPush               @ IF R3 <= 9, LLAMA AL APILADOR
sub r3, r3, $10             @ ENTONCES, SUSTRAE 10 DESDE R3
add r4, r4, $1              @ AÑADE 1 A CONTADOR DE DIVISION
bal loop                    @ REPITE

######## COde Segment  ##################################################

@ Basado en Knuth TAOCP vol. 1 147ff
@ He utilizado las etiquetas y os usos de las variables de Knuth, hasta cierto punto.

@@@@@@@@@@@@@
@ registros @
@@@@@@@@@@@@@

@ r1 apuntar a direcciones de "primos"
@ r3 numero que estamos revisando     ( N e Knuth)
@ r4 recuento de primos               ( J en Knuth)
@ r5 divisores que estamos revisando
@ r6 indice para los divisores principales
@ r7 contendra recordatorio           ( R en Knuth)
@ r8 mantendra el cociente            ( Q en Knuth)
@ r9 numeros de primos buscados.

.section     .bss
.comm prime, 2000           @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS

.section     .data
spc:                        @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS CON 3 ESPACIOS
.ascii " "
len = . - spc
nl:                         @ LINEA NUEVA
      .ascii " "
      
limit:                      @ INDICADOR DEL ULTIMO NUMERO PRIMO QUE NECESITAREMOS

      .long 500
      
.section .text
.global _start
_start:

P1:                         @ CONFIGURAION
ldr r1, =prime              @ EL PUNTO R1 ES "PRIME"
mov r0, $2                  @ EL PRIMER PRIMO ES 2
str r0, [r1]                @ ALMACENAMOS ESTE NUMERO EN "PRIME"
ldr r0, =limit
ldr r9, [r0]                @ R2 MANTIENE EL NUMERO DE PRIMOS QUE BUSCAREMOS
mov r3, $3                  @ INICIALIZA N EN 3
mov r4, $1                  @ INICIALIZA J EN 1

P2:                         @ AQUI LLEGAMOS CUANDO ENCONTRAMOS UN NUMERO PRIMO
add r4, r4, $1              @ SE INCREMENTA J
str r3,  [r1, #4]!          @ ALMACENA N EN "PRIME" (CON WRITEBACK)

P3:   
cmp r4, r9                  @ REVISA SI ESTA HECHO
bge P9                      @ SI ES ASI A P9

P4:
add r3, r3, $2              @ AÑADE 2 A N

P5:                         @ EMPIEZA A VERIFICAR LOS DIVISORES
ldr r6, =prime              @ COPIA EL PUNTERO A START DE "PRIME"
ldr r5, [r6]                @ CARGA EL PRIMER DIVISOR 
mov r7, r3                  @ COPIA N EN R
mov r8, $0                  @ INICIALIZA Q

P6:
cmp r7, r5                  @ IF R>= DIVISOR
subge r7, r7, r5            @ SUSTRAE DIVISOR DESDE R
addge r8, r8, $1            @ INCREMENTA Q
bge P6                      @ REPITE
cmp r7, $0                  @ IF R ==0 ...
beq P4                      @ N NO ES PRIMO, ASI QUE PRUEBA EL SIGUIENTE N

P7:
cmp r8, r5                  @ COMPARE Q CON EL DIVISOR
ble P2                      @ IF Q <= DIVISOR, N ES PRIMO

P8:
mov r7, r3                  @ REINICIA R7 A N
mov r8, $0                  @ REINICIA Q
ldr r5,  [r6, #4]           @ OBTIENE EL SIGUIENTE DIVISOR
bol P6                      @ DIVIDE OTRA VEZ

P9:
mov r0, $1                  @ ELIGE STDOUT
mov r4, $0                  @ USA R4 COMO UN CONTADOR TEMPORAL 
mov r5, $0                  @ R5 CUENTA EL TOTAL DE NUMEROS PRIMOS IMPRESOS
ldr r6, =prime              @ PUNTERO A "PRIME"
ldr r3, [r6]                @ CARGA EL PRIMER NUMERO PRIMO

printloop:
bl print_num                @ LLAMADA DE FUNCION
add r4, $1                  @ AÑADE UNO AL CONTADOR TEMPORAL
add r5, $1                  @ AÑADE UNO AL CONTADOR
cmp r5, r9                  @ AQUI ES DONDE TERMINAMOS?
bge exit                    @ SI ES ASI, SALIDA
cmp r4, $9                  @ AFTER 10 NUMEROS PRIMOS ...
bgt newline                 @ IMPRIME UNA NUEVA LINEA
ble space                   @ AÑADE ESPACIO



space:                      @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =spc                @ IMPRIMIR ESPACIOS
ldr r2, =len
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
bal printLoop               @ CUNTINUA IMPRIMIENDO

newline:                    @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =nl                 @ IMPRIMIR UNA NUEVA LINEA
mov r2, $1
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
mov r4, $0                  @ REINICIA EL CONTADOR TEMPORAL
bal printLoop               @ CONTINUA IMPRIMIENDO


@@@@@@@@@@@@@@@@@@@@@@
@ print_num function @
@@@@@@@@@@@@@@@@@@@@@@

  ####### Data Segment ####################################################
  
print_num:
  stmfd sp!, {r0-r9, lr}    @ PUSH REGS A LA PILA
  mov r4, $0                @ PROPONE CONTADOR DE DIVISION A ZERO
  mov r5, $1                @ PROPONE CONTADOR CHAR A 1
  
loop:                       @ DIVISION DE RUTINA
cmp r3, $9
ble stackPush               @ IF R3 <= 9, LLAMA AL APILADOR
sub r3, r3, $10             @ ENTONCES, SUSTRAE 10 DESDE R3
add r4, r4, $1              @ AÑADE 1 A CONTADOR DE DIVISION
bal loop                    @ REPITE

stackPush:
add r5, r5, $1              @ INCREMENTA EL CONTADOR CHAR
orr r0, r3, $0x30           @ LOGICO OR - AÑADE 48 A DIDITOS PARA OBTERE CODIGO ASCII
stmfd sp!, {r0}             @ EMPUJA DENTO DE LA PILA
cmp r4, $0                  @ SI EL CONTADOR DE DIVISION ES ZERO...
beq printChars              @ LLAMA LA FUNCION DE IMPRESION
mov r3, r4                  @ ENTONCES, CARGA CONTADOR DE DIVISION EN R3
mov r4, $0                  @REINICIA CONTADOR DE DIVISION 
bal loop                    @REGRESA AL TOPE DE LOOP

printChars:
mov r1, sp                  @ USA EL APUNTADOR DE LA PILA PARA PROVEER CODIGO ASCII
mov r0, $1                  @ STDOUT ES EL ARCHIVO DESCRIPTOR 1
mov r2, $1                  @ LONGITUD DE IMPRIMIR ES 1
mov r7, $4                  @ ESCRIBE SYSCALL
svc $0                      @ WAKE KERNEL!!!!!
subs r5, r5, $1             @ DECREMENTA EL CONTADOR STRING Y ESTABLECE LA BANDERA
ble return                  @ REGRESA SI ESTA HECHO
ldmfd sp!, {0}              @ JALA EL SIGUIENTE CHAR DESDE LA PILA
bal prinntChars             @ OBTIENE EL SIGUIENTE CHAR
return:
ldmfd sp!, {r0-r9, pc}      @ REINICIA REGISTROS

exit:                       @ IMPRIME UNA NUEVA LINEA
mov r0, $1
ldr r1, =nl
mov r7, $4
svc $0
mov r7, $1                  @ EXIT
svc $0

.end
add r5, r5, $1              @ INCREMENTA EL CONTADOR CHAR
orr r0, r3, $0x30           @ LOGICO OR - AÑADE 48 A DIDITOS PARA OBTERE CODIGO ASCII
stmfd sp!, {r0}             @ EMPUJA DENTO DE LA PILA
cmp r4, $0                  @ SI EL CONTADOR DE DIVISION ES ZERO...
beq printChars              @ LLAMA LA FUNCION DE IMPRESION
mov r3, r4                  @ ENTONCES, CARGA CONTADOR DE DIVISION EN R3
mov r4, $0                  @REINICIA CONTADOR DE DIVISION 
bal loop                    @REGRESA AL TOPE DE LOOP

printChars:
mov r1, sp                  @ USA EL APUNTADOR DE LA PILA PARA PROVEER CODIGO ASCII
mov r0, $1                  @ STDOUT ES EL ARCHIVO DESCRIPTOR 1
mov r2, $1                  @ LONGITUD DE IMPRIMIR ES 1
mov r7, $4                  @ ESCRIBE SYSCALL
svc $0                      @ WAKE KERNEL!!!!!
subs r5, r5, $1             @ DECREMENTA EL CONTADOR STRING Y ESTABLECE LA BANDERA
ble return                  @ REGRESA SI ESTA HECHO
ldmfd sp!, {0}              @ JALA EL SIGUIENTE CHAR DESDE LA PILA
bal prinntChars             @ OBTIENE EL SIGUIENTE CHAR
return:
ldmfd sp!, {r0-r9, pc}      @ REINICIA REGISTROS

exit:                       @ IMPRIME UNA NUEVA LINEA
mov r0, $1
ldr r1, =nl
mov r7, $4
svc $0
mov r7, $1                  @ EXIT
svc $0

.end           @ AÑADE UNO AL CONTADOR
cmp r5, r9                  @ AQUI ES DONDE TERMINAMOS?
bge exit                    @ SI ES ASI, SALIDA
cmp r4, $9                  @ AFTER 10 NUMEROS PRIMOS ...
bgt newline                 @ IMPRIME UNA NUEVA LINEA
ble space                   @ AÑADE ESPACIO



space:                      @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =spc                @ IMPRIMIR ESPACIOS
ldr r2, =len
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
bal printLoop               @ CUNTINUA IMPRIMIENDO

newline:                    @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =nl                 @ IMPRIMIR UNA NUEVA LINEA
mov r2, $1
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
mov r4, $0                  @ REINICIA EL CONTADOR TEMPORAL
bal printLoop               @ CONTINUA IMPRIMIENDO


@@@@@@@@@@@@@@@@@@@@@@
@ print_num function @
@@@@@@@@@@@@@@@@@@@@@@

  ####### Data Segment ####################################################
  
print_num:
  stmfd sp!, {r0-r9, lr}    @ PUSH REGS A LA PILA
  mov r4, $0                @ PROPONE CONTADOR DE DIVISION A ZERO
  mov r5, $1                @ PROPONE CONTADOR CHAR A 1
  
loop:                       @ DIVISION DE RUTINA
cmp r3, $9
ble stackPush               @ IF R3 <= 9, LLAMA AL APILADOR
sub r3, r3, $10             @ ENTONCES, SUSTRAE 10 DESDE R3
add r4, r4, $1              @ AÑADE 1 A CONTADOR DE DIVISION
bal loop                    @ REPITE

stackPush:
add r5, r5, $1              @ INCREMENTA EL CONTADOR CHAR
orr r0, r3, $0x30           @ LOGICO OR - AÑADE 48 A DIDITOS PARA OBTERE CODIGO ASCII
stmfd sp!, {r0}             @ EMPUJA DENTO DE LA PILA
cmp r4, $0                  @ SI EL CONTADOR DE DIVISION ES ZERO...
beq printChars              @ LLAMA LA FUNCION DE IMPRESION
mov r3, r4                  @ ENTONCES, CARGA CONTADOR DE DIVISION EN R3
mov r4, $0                  @REINICIA CONTADOR DE DIVISION 
bal loop                    @REGRESA AL TOPE DE LOOP

printChars:
mov r1, sp                  @ USA EL APUNTADOR DE LA PILA PARA PROVEER CODIGO ASCII
mov r0, $1                  @ STDOUT ES EL ARCHIVO DESCRIPTOR 1
mov r2, $1                  @ LONGITUD DE IMPRIMIR ES 1
mov r7, $4                  @ ESCRIBE SYSCALL
svc $0                      @ WAKE KERNEL!!!!!
subs r5, r5, $1             @ DECREMENTA EL CONTADOR STRING Y ESTABLECE LA BANDERA
ble return                  @ REGRESA SI ESTA HECHO
ldmfd sp!, {0}              @ JALA EL SIGUIENTE CHAR DESDE LA PILA
bal prinntChars             @ OBTIENE EL SIGUIENTE CHAR
return:
ldmfd sp!, {r0-r9, pc}      @ REINICIA REGISTROS

exit:                       @ IMPRIME UNA NUEVA LINEA
mov r0, $1
ldr r1, =nl
mov r7, $4
svc $0
mov r7, $1                  @ EXIT
svc $0

.end
@ Basado en Knuth TAOCP vol. 1 147ff
@ He utilizado las etiquetas y os usos de las variables de Knuth, hasta cierto punto.

@@@@@@@@@@@@@
@ registros @
@@@@@@@@@@@@@

@ r1 apuntar a direcciones de "primos"
@ r3 numero que estamos revisando     ( N e Knuth)
@ r4 recuento de primos               ( J en Knuth)
@ r5 divisores que estamos revisando
@ r6 indice para los divisores principales
@ r7 contendra recordatorio           ( R en Knuth)
@ r8 mantendra el cociente            ( Q en Knuth)
@ r9 numeros de primos buscados.

.section     .bss
.comm prime, 2000           @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS

.section     .data
spc:                        @RESERVA ESPACIO PARA LOS NUMEROS PRIMOS CON 3 ESPACIOS
.ascii " "
len = . - spc
nl:                         @ LINEA NUEVA
      .ascii " "
      
limit:                      @ INDICADOR DEL ULTIMO NUMERO PRIMO QUE NECESITAREMOS

      .long 500
      
.section .text
.global _start
_start:

P1:                         @ CONFIGURAION
ldr r1, =prime              @ EL PUNTO R1 ES "PRIME"
mov r0, $2                  @ EL PRIMER PRIMO ES 2
str r0, [r1]                @ ALMACENAMOS ESTE NUMERO EN "PRIME"
ldr r0, =limit
ldr r9, [r0]                @ R2 MANTIENE EL NUMERO DE PRIMOS QUE BUSCAREMOS
mov r3, $3                  @ INICIALIZA N EN 3
mov r4, $1                  @ INICIALIZA J EN 1

P2:                         @ AQUI LLEGAMOS CUANDO ENCONTRAMOS UN NUMERO PRIMO
add r4, r4, $1              @ SE INCREMENTA J
str r3,  [r1, #4]!          @ ALMACENA N EN "PRIME" (CON WRITEBACK)

P3:   
cmp r4, r9                  @ REVISA SI ESTA HECHO
bge P9                      @ SI ES ASI A P9

P4:
add r3, r3, $2              @ AÑADE 2 A N

P5:                         @ EMPIEZA A VERIFICAR LOS DIVISORES
ldr r6, =prime              @ COPIA EL PUNTERO A START DE "PRIME"
ldr r5, [r6]                @ CARGA EL PRIMER DIVISOR 
mov r7, r3                  @ COPIA N EN R
mov r8, $0                  @ INICIALIZA Q

P6:
cmp r7, r5                  @ IF R>= DIVISOR
subge r7, r7, r5            @ SUSTRAE DIVISOR DESDE R
addge r8, r8, $1            @ INCREMENTA Q
bge P6                      @ REPITE
cmp r7, $0                  @ IF R ==0 ...
beq P4                      @ N NO ES PRIMO, ASI QUE PRUEBA EL SIGUIENTE N

P7:
cmp r8, r5                  @ COMPARE Q CON EL DIVISOR
ble P2                      @ IF Q <= DIVISOR, N ES PRIMO

P8:
mov r7, r3                  @ REINICIA R7 A N
mov r8, $0                  @ REINICIA Q
ldr r5,  [r6, #4]           @ OBTIENE EL SIGUIENTE DIVISOR
bol P6                      @ DIVIDE OTRA VEZ

P9:
mov r0, $1                  @ ELIGE STDOUT
mov r4, $0                  @ USA R4 COMO UN CONTADOR TEMPORAL 
mov r5, $0                  @ R5 CUENTA EL TOTAL DE NUMEROS PRIMOS IMPRESOS
ldr r6, =prime              @ PUNTERO A "PRIME"
ldr r3, [r6]                @ CARGA EL PRIMER NUMERO PRIMO

printloop:
bl print_num                @ LLAMADA DE FUNCION
add r4, $1                  @ AÑADE UNO AL CONTADOR TEMPORAL
add r5, $1                  @ AÑADE UNO AL CONTADOR
cmp r5, r9                  @ AQUI ES DONDE TERMINAMOS?
bge exit                    @ SI ES ASI, SALIDA
cmp r4, $9                  @ AFTER 10 NUMEROS PRIMOS ...
bgt newline                 @ IMPRIME UNA NUEVA LINEA
ble space                   @ AÑADE ESPACIO



space:                      @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =spc                @ IMPRIMIR ESPACIOS
ldr r2, =len
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
bal printLoop               @ CUNTINUA IMPRIMIENDO

newline:                    @ SALTAMOS AQUI SI
mov r0, $1                  @ VAMOS A
ldr r1, =nl                 @ IMPRIMIR UNA NUEVA LINEA
mov r2, $1
mov r7, $4
svc $0
ldr r3, [r6, #4]            @ CARGA EL SIGUIENTE NUMERO PRIMO
mov r4, $0                  @ REINICIA EL CONTADOR TEMPORAL
bal printLoop               @ CONTINUA IMPRIMIENDO


@@@@@@@@@@@@@@@@@@@@@@
@ print_num function @
@@@@@@@@@@@@@@@@@@@@@@

  ####### Data Segment ####################################################
  
print_num:
  stmfd sp!, {r0-r9, lr}    @ PUSH REGS A LA PILA
  mov r4, $0                @ PROPONE CONTADOR DE DIVISION A ZERO
  mov r5, $1                @ PROPONE CONTADOR CHAR A 1
  
loop:                       @ DIVISION DE RUTINA
cmp r3, $9
ble stackPush               @ IF R3 <= 9, LLAMA AL APILADOR
sub r3, r3, $10             @ ENTONCES, SUSTRAE 10 DESDE R3
add r4, r4, $1              @ AÑADE 1 A CONTADOR DE DIVISION
bal loop                    @ REPITE

stackPush:
add r5, r5, $1              @ INCREMENTA EL CONTADOR CHAR
orr r0, r3, $0x30           @ LOGICO OR - AÑADE 48 A DIDITOS PARA OBTERE CODIGO ASCII
stmfd sp!, {r0}             @ EMPUJA DENTO DE LA PILA
cmp r4, $0                  @ SI EL CONTADOR DE DIVISION ES ZERO...
beq printChars              @ LLAMA LA FUNCION DE IMPRESION
mov r3, r4                  @ ENTONCES, CARGA CONTADOR DE DIVISION EN R3
mov r4, $0                  @REINICIA CONTADOR DE DIVISION 
bal loop                    @REGRESA AL TOPE DE LOOP

printChars:
mov r1, sp                  @ USA EL APUNTADOR DE LA PILA PARA PROVEER CODIGO ASCII
mov r0, $1                  @ STDOUT ES EL ARCHIVO DESCRIPTOR 1
mov r2, $1                  @ LONGITUD DE IMPRIMIR ES 1
mov r7, $4                  @ ESCRIBE SYSCALL
svc $0                      @ WAKE KERNEL!!!!!
subs r5, r5, $1             @ DECREMENTA EL CONTADOR STRING Y ESTABLECE LA BANDERA
ble return                  @ REGRESA SI ESTA HECHO
ldmfd sp!, {0}              @ JALA EL SIGUIENTE CHAR DESDE LA PILA
bal prinntChars             @ OBTIENE EL SIGUIENTE CHAR
return:
ldmfd sp!, {r0-r9, pc}      @ REINICIA REGISTROS

exit:                       @ IMPRIME UNA NUEVA LINEA
mov r0, $1
ldr r1, =nl
mov r7, $4
svc $0
mov r7, $1                  @ EXIT
svc $0

.end
